export default function debounce(fn, duration = 500, immediate = false) {
  let timer = null;
  let isInvoke = false
  const _debounce = function (...args) {
    return new Promise((resolve, reject) => {
      if (timer) {
        clearTimeout(timer)
        timer = null
      }

      if (immediate && !isInvoke) {
        const result = fn.apply(this, args);
        resolve(result);
        isInvoke = true
      } else {
        timer = setTimeout(() => {
          const result = fn.apply(this, args);
          resolve(result)

          clearTimeout(timer)
          timer = null

          isInvoke = false
        }, duration)
      }

    })
  }

  _debounce.cancel = function () {
    if (timer) {
      clearTimeout(timer)
      timer = null
    }
  }

  return _debounce
}